package net.hn.hnms.service;

import lombok.extern.slf4j.Slf4j;
import net.hn.hnms.entity.FtpConfig;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.util.StringUtils;

import java.io.*;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;

/**
 * 智呈物联 pan'sx
 * 2023/10/20 14:24
 * 1.0 version
 */
@Slf4j
public class FtpUploadService {

    public static boolean cronUploadFile(FtpConfig ftpConfig) {
        boolean result = false;
        FTPClient ftp = new FTPClient();
        try {
            int reply;
            ftp.connect(ftpConfig.getFtpServer(), ftpConfig.getFtpPort());// 连接FTP服务器
            // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
            ftp.login(ftpConfig.getUserName(), ftpConfig.getPassword());// 登录

            ftp.setControlEncoding(System.getProperty("file.encoding"));
            reply = ftp.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftp.disconnect();
                return result;
            }
            //切换到上传目录
            if (!ftp.changeWorkingDirectory(ftpConfig.getTagetDirectory())) {
                //如果目录不存在创建目录
                String[] dirs = ftpConfig.getTagetDirectory().split("/");
                String tempPath = "";
                for (String dir : dirs) {
                    if (null == dir || "".equals(dir)) continue;
                    tempPath += "/" + dir;
                    if (!ftp.changeWorkingDirectory(tempPath)) {  //进不去目录，说明该目录不存在
                        if (!ftp.makeDirectory(tempPath)) { //创建目录
                            //如果创建文件目录失败，则返回
                            System.out.println("创建文件目录" + tempPath + "失败");
                            return result;
                        } else {
                            //目录存在，则直接进入该目录
                            ftp.changeWorkingDirectory(tempPath);
                        }
                    }
                }
            }
            if(ftpConfig.getEnterLocalPassiveMode()) {
                ftp.enterLocalPassiveMode();
            }
            FTPFile[] fs = ftp.listFiles();

            List<String> filenames = new ArrayList<>();
            for (FTPFile file : fs) {
                filenames.add(file.getName());
            }
            File file = new File(ftpConfig.getSourceDirectory());

            File[] files = file.listFiles();
            for (int i = 0; i < files.length; i++) {
                File fe = files[i];
                if (fe.getName().contains(ftpConfig.getExclude())) {
                    continue;
                }
                if (filenames.contains(fe.getName())) {
                    continue;
                }
                FileInputStream input = new FileInputStream(fe);
                //设置上传文件的类型为二进制类型
                ftp.setFileType(FTP.BINARY_FILE_TYPE);
                //上传文件
                if (!ftp.storeFile(fe.getName(), input)) {
//                    return result;
                }
                input.close();
                result = true;
            }
            ftp.logout();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftp.isConnected()) {
                try {
                    ftp.disconnect();
                } catch (IOException ioe) {
                }
            }
        }
        return result;
    }

    public static void listenUploadFile(FtpConfig ftpConfig) {

        Path dir = Paths.get(ftpConfig.getSourceDirectory());
        WatchService watchService = null;
        FTPClient ftp = new FTPClient();
        try {
            watchService = FileSystems.getDefault().newWatchService();
            dir.register(watchService, StandardWatchEventKinds.ENTRY_MODIFY, StandardWatchEventKinds.ENTRY_CREATE);
            while (true) {
                WatchKey key = watchService.take();
                for (WatchEvent<?> event : key.pollEvents()) {
                    Path fileName = (Path) event.context();
                    File file = dir.resolve(fileName).toFile();
                    if (!StringUtils.isEmpty(ftpConfig.getExclude())&&file.getName().contains(ftpConfig.getExclude())) {
                        continue;
                    }
                    if(!StringUtils.isEmpty(ftpConfig.getSuffix())&&!file.getName().toLowerCase().contains(ftpConfig.getSuffix().toLowerCase())){
                        continue;
                    }
                    int reply;
                    ftp.connect(ftpConfig.getFtpServer(), ftpConfig.getFtpPort());// 连接FTP服务器
                    // 如果采用默认端口，可以使用ftp.connect(host)的方式直接连接FTP服务器
                    ftp.login(ftpConfig.getUserName(), ftpConfig.getPassword());// 登录

                    ftp.setControlEncoding(System.getProperty("file.encoding"));
                    reply = ftp.getReplyCode();
                    if (!FTPReply.isPositiveCompletion(reply)) {
                        ftp.disconnect();
                    }
                    if (!ftp.changeWorkingDirectory(ftpConfig.getTagetDirectory())) {
                        //如果目录不存在创建目录
                        String[] dirs = ftpConfig.getTagetDirectory().split("/");
                        String tempPath = "";
                        for (String tagetDirir : dirs) {
                            if (null == tagetDirir || "".equals(tagetDirir)) continue;
                            tempPath += "/" + tagetDirir;
                            if (!ftp.changeWorkingDirectory(tempPath)) {  //进不去目录，说明该目录不存在
                                if (!ftp.makeDirectory(tempPath)) { //创建目录
                                    //如果创建文件目录失败，则返回
                                    log.info("创建文件目录" + tempPath + "失败");
                                } else {
                                    //目录存在，则直接进入该目录
                                    ftp.changeWorkingDirectory(tempPath);
                                }
                            }
                        }
                    }
                    if(ftpConfig.getEnterLocalPassiveMode()) {
                        ftp.enterLocalPassiveMode();
                    }

                    FileInputStream input = new FileInputStream(file);
                    ftp.setFileType(FTP.BINARY_FILE_TYPE);
                    //上传文件
                    if (!ftp.storeFile(file.getName(), input)) {
                        log.error(file.getName() + "上传失败");
                    }else{
                        log.info(file.getName() + "上传成功");
                    }
                    input.close();
                    ftp.logout();
                    if (ftp.isConnected()) {
                        ftp.disconnect();
                    }
                }
                if (!key.reset()) { // 重设WatchKey
                    break;
                }
            }
        } catch (IOException | InterruptedException e) {
            e.printStackTrace();
            log.error(e.getMessage());
        }
        if (ftp.isConnected()) {
            try {
                ftp.disconnect();
            } catch (IOException ioe) {
            }
        }

    }
}
